<template>
    <div class="code-mirror">
        <Codemirror
            class="cm-container"
            v-model:value="state.code"
            :options="state.cmOptions"
            border
            height="300"
            width="100%"
            @change="onChange"
            @input="onInput"
            @ready="onReady"
        />
    </div>
</template>

<script setup>
import { inject, ref, onMounted, reactive, nextTick, watchEffect } from 'vue';
import "codemirror/mode/javascript/javascript.js";
import 'codemirror/addon/lint/javascript-lint.js';
import 'codemirror/addon/hint/show-hint.css';
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/javascript-hint.js';

import 'codemirror/addon/lint/json-lint'
import Codemirror from "codemirror-editor-vue3";
import 'codemirror/addon/scroll/simplescrollbars.css'
import 'codemirror/addon/scroll/simplescrollbars'
// 折叠
import 'codemirror/addon/fold/foldgutter.css'
import 'codemirror/addon/fold/foldcode'
import 'codemirror/addon/fold/foldgutter'
import 'codemirror/addon/fold/brace-fold'
import 'codemirror/addon/fold/comment-fold'

import { javascript } from "@codemirror/lang-javascript";
import { autocompletion } from "@codemirror/autocomplete";

const props = defineProps({
    readOnly:{
        type:Boolean,
        default:()=>true
    },
    type:{
        type:String,
        default:()=>'json'
    }
})

const cmRef = ref();

const state = reactive({
    code:"",
    cmOptions:{
        mode: "application/json",
        scrollbarStyle: 'simple',
        readOnly: true,
        lineNumbers: true, // 是否显示行号
        lineWrapping: true, // 是否应滚动或换行以显示长行
        lint: true,
        hintOptions: {
            completeSingle: false,
        },
        extraKeys: { Ctrl: 'autocomplete' },
        autocorrect: true,
        lineWiseCopyCut: true, // 在没有选择的情况下进行复制或剪切将复制或剪切有光标的整行。
        showCursorWhenSelecting: true, // 选择处于活动状态时是否应绘制光标
        maxHighlightLength: Infinity, // 显示长行的时候 这个值是不限制，如果要做限制的话，值是number类型
        matchBrackets: true, // 光标匹配括号
        foldGutter: true,
        autoCloseTags: true,
        matchTags: { bothTags: true },
        styleActiveLine: true,
        smartIndent: true,
        // gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'],
        gutters: ['CodeMirror-lint-markers'],
    }
})

watchEffect(()=>{
    state.cmOptions.readOnly = props.readOnly
    if(props.type === 'json'){
        state.cmOptions.mode = 'application/json'
    }else if(props.type === 'javascript'){
        state.cmOptions.mode = 'javascript'
    }
    nextTick(()=>{
        cmRef.value.refresh()
    })
})

const onChange = (val, cm) => {
    // console.log(val);
    // console.log(cm.getValue());
};

const onInput = (val) => {
    // console.log(val);
};

const onReady = (cm) => {
    cmRef.value = cm
};

const getValue = ()=>{
    return cmRef.value.getValue() || state.code
}

const setValue = (val)=>{
    typeof val !== 'string' && (val = JSON.stringify(val, null, 2))
    state.code = val
}

onMounted(()=>{
    nextTick(()=>{
        cmRef.value.refresh()
    })
})

defineExpose({
    getValue,
    setValue
})
</script>

<style lang='scss' scoped>
:deep(.CodeMirror-simplescroll-vertical) {
    div{
        width: 75%;
    }
}
:deep(.CodeMirror-simplescroll-horizontal){
    div{
        height: 75%;
    }
}
</style>